<template>
  <div ref="cascader" class="cascader pointer" @click="show">
    <img :src="cascaderL" alt="">
    <p class="font-lan-m">{{ getLabel() }}</p>
    <div class="d-flex ai-center">
      <img v-if="modelValue.length > 0" class="clearImg mr-1" :src="clear" alt="" @click.stop="clickClear">
      <img :class="['cascaderImg', showcascader ? 'rotate' : '']" :src="cascaderR" alt="">
    </div>
    <div v-show="showcascader" class="cascaderPopper" ref="cascaderPopper">
      <div class="cascaderDropDown">
        <cascaderItem :options="options" :selectItems="selectItems" :modelValue="modelValue"  :label="label" :value="value" :level="level" @unfoldChange="unfoldChange" @change="change"/>
      </div>
      <span class="popperArrow"></span>
    </div>
  </div>
</template>
  
<script lang="ts">
import {
  ref,
  reactive,
  onMounted,
  watch,
  onBeforeMount,
  onBeforeUnmount,
  defineComponent,
} from "vue";
import cascaderItem from "./cascaderItem.vue";
import { progressProps } from "element-plus";


// 声明类型
const PropsType = {
  placeholder: {
    type: String,
    default: '',
    require: true
  },
  options: {
    type: Array,
    default: [],
    require: true
  },
  modelValue: {
    type: Array,
    default: [],
    require: true
  },
  label: {
    type: String,
    default: 'label',
  },
  value: {
    type: String,
    default: 'value',
  },
  children: {
    type: String,
    default: 'children',
  },
  level: {
    type: Number,
    default: 0,
  }
} as const

// 声明类型
export default defineComponent({
  props: PropsType,
  components: {
    cascaderItem
  },
  setup(props, context) {
    //变量
    const cascader = ref(null)
    let selectItems = ref(props.modelValue.map(item=>item))
    const cascaderPopper = ref(null)
    const cascaderData = reactive({
      top: 0,
      left: 0,
      minWidth: 0
    })
    const cascaderL = require("@/assets/img/select-left.png");
    const cascaderR = require("@/assets/img/select-right.png");
    const clear = require("@/assets/img/close-circle.png");
    const showcascader = ref(false)
    const show = () => {
      let data = cascader.value.getBoundingClientRect()
      cascaderData.top = data.top + data.height + 10
      cascaderData.left = data.left
      cascaderData.minWidth = data.width
      showcascader.value = !showcascader.value
    }

    watch(
      () => props,
      (val: any) => {
        //
        
        // 手动触发更新
        
      },
      {
        immediate: true,
        deep: true
      }
    )

    const clickClear = () => {
      context.emit('update:modelValue', [])
      context.emit('change', [])
    }

    const getLabel = () => {
      return props.modelValue.length == 0 ? props.placeholder : props.modelValue.map(item=>item[props.label]).join('/')
    }

    const change = (val)=>{
      let arr = selectItems.value.map(item=>item)
      context.emit('update:modelValue', arr)
      context.emit('change', arr)
    }

    const unfoldChange = (val)=>{
      selectItems.value.splice(val.level, 1, val.data); // 替换当前点击位置信息
      selectItems.value.splice(val.level + 1); // 删除当前点击位置之后的数据
    }

    const closecascaderHandler = (e) => {
      //获取DOM元素的引用
      if(e.target.id == 'cascader') return
      if (cascader.value && cascader.value.contains(e.target)) {
        return;
      }
      showcascader.value = false;
    };

    onBeforeMount(() => {
      // 在DOM元素渲染之前开始监听mousedown事件
      document.body.addEventListener("mousedown", closecascaderHandler);
    });

    onBeforeUnmount(() => {
      // 在Vue文件销毁的时候移除这个事件
      document.body.removeEventListener("mousedown", closecascaderHandler);
    });

    onMounted(() => {
      //

    })

    // return
    return {
      cascader,
      cascaderPopper,
      cascaderL,
      cascaderR,
      clear,
      showcascader,
      cascaderData,
      selectItems,
      clickClear,
      getLabel,
      show,
      change,
      unfoldChange
    };
  },

});
</script>
  
<style lang="scss" scoped>
@import "@/assets/scss/index.scss";

.cascader {
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
  padding: 4px 8px;
  background: linear-gradient(90deg, rgba(82, 147, 204, 0) 0%, #5293CC 47%, rgba(82, 147, 204, 0) 100%);
  border-radius: 4px 4px 4px 4px;
  opacity: 1;
  border: 1px solid;
  border-image: linear-gradient(90deg, rgba(153, 207, 255, 0), rgba(153, 207, 255, 1), rgba(153, 207, 255, 0)) 1 1;

  .title {
    font-size: 14px;
    font-weight: 500;
    color: #FFFFFF;
    line-height: 20px;
  }

  .clearImg{
    width: 16px;
    height: 16px;
  }
  .cascaderImg {
    transition: transform 0.3s;
    transform: rotate(0);
  }

  .rotate {
    transform: rotate(-180deg);
  }

  --inset: v-bind(`${cascaderData.top}px auto auto ${cascaderData.left}px`);
  --min-width: v-bind(`${cascaderData.minWidth}px`);
  .cascaderPopper {
    position: fixed;
    inset: var(--inset);
    z-index: 2000;
    min-width: 50px;
    color: #fff;
    background: rgba(20, 69, 102, 1);
    border-radius: 4px;
    opacity: 1;
    box-shadow: 0px 0px 12px rgba(0, 0, 0, .12);
    .cascaderDropDown {
      min-width: 120px;
      padding: 12px 16px;

      .active {
        background: linear-gradient(270deg, #ccb17a00 0%, #E5D38A 100%);
        opacity: 1;
      }
    }

    .popperArrow {
      position: absolute;
      left: 50%;
      top: -5px;
      transform: translateX(-50%) rotate(45deg);
      width: 10px;
      height: 10px;
      background: rgba(60 ,114 ,151, 1);
      z-index: -1;
    }
  }
}</style>
  